#include "StdAfx.h"
#include "Helper.h"

Helper::Helper(void)
{
  m_binTree     = new binaryTree();
  m_edgeMap     = new edgeMapHelper(); 
  //m_currEdge    = new figureEdge();
  m_helperExist = false; 
}

Helper::~Helper(void)
{
  delete(m_edgeMap);
  delete(m_binTree);
  //delete(m_currEdge);
}

void Helper::Init()
{
  CleanQueues();
}

void Helper::OrderEdges(const figureVertice & v)
{
  //First clean the queue
  
  //The first we take all edges from edgeList
  //created in runtime :)
  
  /*
  figureEdge e;
  edgeIterator it;
  for(it = m_edgeList->begin();
      it != m_edgeList->end();
      it ++)
  {
    e = *it;
    if((e._begin.y > v.y) && (e._end.y <= v.y))
    {
      if((e._begin.x < v.x) || (e._end.x < v.x))
      {
        //All edges left of vertice
        m_edgeLeft->push(e);
      }
      if((e._begin.x > v.x) || (e._end.x > v.x))
      {
        //All edges left of vertice
        m_edgeRight->push(e);
      }
    }
  }*/
}


void Helper::CleanQueues()
{
  m_binTree->clear();
  m_edgeMap->clear();
}


void Helper::InsertEdge(const figureEdge & edge, const figureVertice & vertice)
{
  edgePair pair(edge,vertice);
  m_edgeMap->insert(pair);
  //(*m_edgeMap)[edge] = vertice;
#ifdef DEBUG
  TestMap();
#endif
}

void Helper::UpdateEgde(const figureEdge & edge, const figureVertice & vertice)
{
  //edgePair pair(edge,vertice);
  edgeMapIter it;

  it = m_edgeMap->find(edge);
  if(it != m_edgeMap->end())
  {
    m_edgeMap->erase(it);
  }
  InsertEdge(edge, vertice);
}

void Helper::UpdateCurrEgde(const figureVertice & v)
{
  UpdateEgde(m_currEdge,v);
}

figureVertice & Helper::FindVertice(const figureVertice & v)
{
  //We have to find on the vertice list
  //the the lowest vertex between both edges (ej and ek)
  //The edges are stored in the searchTree
  //which is updated in runtime
  //So we get the list of all edges stored in Tree
  //and looking for edges which are fulfil the condition
  binaryTreeIterator it;
  figureEdge         edge;
  int                order = 0;
  double             x_coord;
  int                lenght = 100000;
  int                v_len;

  m_helperExist = false;
  m_currEdge._begin.x = -1;
  m_currEdge._begin.y = -1;

  for(it = m_binTree->begin();
      it != m_binTree->end();
      it++)
  {
    edge = *it;
    if((((edge._begin.y >= v.y) && (edge._end.y < v.y)) ||
       ((edge._begin.y < v.y) && (edge._end.y >= v.y))) &&
       (edge._begin.y > edge._end.y))  //the interior of figure has to be on the right
    {
      //The edge's end and begin is between passed vertice
      //and it is on the left of given vertices
      //Now we have to find the closest edge to given vertice
      //TODO: How to do it ??
      //(((_ed._begin.x >= v.x) && (_ed._end.x < v.x)) ||
      // ((_ed._begin.x < v.x) && (_ed._end.x >= v.x))))
      m_linear.Create(edge._begin, edge._end);
      x_coord = m_linear.CalculateValue(v,1).x;

      if(x_coord < v.x) //we have an edge directly on the left of vertice
      {
        m_vector.SetVector(edge._begin, v);
        v_len = m_vector.GetLength();
        if(lenght > v_len)
        {
          lenght        = v_len;
          m_helperExist = true;
          //m_helper      = _ed._begin; //who did it so stupid
          m_helper      = GetHelper(edge);
          m_currEdge    = edge; 
        }
      }
    }
  }
/*TODO: this subroutine has to be based on searchTree
  m_helper = el._begin;
  for(it = m_vertList->begin();
      it != m_vertList->end();
      it ++)
  {
    //Check if the vertice is between edges
    //just x-coordinate but less the el begin and er end
    //and also v has to have y-coordinate less the both edges
    v = *it;
    if((v.x > el._begin.x) && (v.x < er._end.x))
    {
      if((v.y <= el._begin.y) && (v.y <= er._end.y))
      {
        m_helper = v;
        found    = true;
      }      
    }
  }
  */
  return m_helper;
}


bool Helper::IsFound()
{
  return (m_helperExist);
}

figureVertice & Helper::GetHelper(const figureEdge & edge)
{
#ifdef DEBUG
  TestMap();
#endif
  m_helper = m_edgeMap->find(edge)->second;
  return m_helper;
}

  
void Helper::AddEdgeBT(const figureEdge & edge)
{
  m_binTree->InsertEdge(edge);
}

void Helper::DelEdgeBT(const figureEdge & edge)
{
  m_binTree->RemoveEdge(edge);
}


#ifdef DEBUG
  void  Helper::TestMap()
  {
    edgeMapIter it;
    figureVertice v;
    figureEdge    e;
    for(it = m_edgeMap->begin();
        it != m_edgeMap->end();
        it++)
    {
      e = (*it).first;
      v = (*it).second;
    }
  }
#endif